package com.tinusgraglin.enclusiv.ui.screens

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.tinusgraglin.enclusiv.R
import com.tinusgraglin.enclusiv.Util
import com.tinusgraglin.enclusiv.datalayer.ShowedArticleProfile
import com.tinusgraglin.enclusiv.ui.EnclusivViewModelFactory
import com.tinusgraglin.enclusiv.ui.viewmodel.MainActivityViewModel
import com.tinusgraglin.enclusiv.ui.UniverseScreen
import com.tinusgraglin.enclusiv.ui.components.MyBottomNav.MyBottomNavigationItem
import com.tinusgraglin.enclusiv.ui.theme.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    private val viewModel: MainActivityViewModel by viewModels {
        EnclusivViewModelFactory()
    }
    private lateinit var readArticleLauncher: ActivityResultLauncher<Pair<Int, ShowedArticleProfile>>
    private lateinit var writeArticleLauncher: ActivityResultLauncher<Unit>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MainScreen()
        }
        if (savedInstanceState == null)
            viewModel.getOneShotRecommended()
        readArticleLauncher = registerForActivityResult(Util.Companion.ReadArticleContract()) {
            if (it != null) {
                viewModel.toggleRecommendedArticleUserArticleStats(it.first, it.second)
            }
        }
        writeArticleLauncher = registerForActivityResult(Util.Companion.WriteArticleContract()) {
            Log.d("##DBG 3291", "BACK HERE")
            if (it != null) {
                Log.d("##DBG 3291", "uploaded id=${it.first}")
                viewModel.addMyNewlyUploadedArticle(it.first, it.second)
            }
        }
    }

    private var onBackExit = false

    private val waitAndCancelOnBackExit = suspend {
        delay(500)
        onBackExit = false
    }

    override fun onBackPressed() {
        if (!onBackExit) {
            onBackExit = true
            lifecycleScope.launch {
                waitAndCancelOnBackExit()
            }
        } else {
            finishAffinity()
        }
    }

    @Preview
    @Composable
    fun MainScreen() {
        EnclusivTheme {
            val navController = rememberNavController()
            Scaffold(
                bottomBar = { BottomNav(navController) },
                floatingActionButtonPosition = FabPosition.Center,
                isFloatingActionButtonDocked = true,
                floatingActionButton = { NewArticleFab() }
            ) {
                NavHost(
                    modifier = Modifier.padding(it),
                    navController = navController,
                    startDestination = "universe"
                ) {
                    composable("universe") {
                        UniverseScreen(viewModel) { i, article ->
                            readArticleLauncher.launch(Pair(i, article!!))
                        }
                    }
                    composable("me") {
                        MeScreen(viewModel)
                    }
                }
            }
        }
    }

    sealed class BottomNavItems(val route: String, val titleResource: Int, val iconUnselected: Int, val iconSelected: Int) {
        object Universe: BottomNavItems("universe", R.string.ui_main_bottom_nav_universe, R.drawable.universe_2, R.drawable.universe_2_chl)
        object Me: BottomNavItems("me", R.string.ui_main_bottom_nav_me, R.drawable.planet_2_1, R.drawable.planet_2_1_chl)
    }

    @Composable
    fun NewArticleFab() {
        Button(
            modifier = Modifier
                .size(64.dp),
            onClick = {
                writeArticleLauncher.launch(Unit)
            },
            colors = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent),
            shape = CircleShape,
            contentPadding = PaddingValues()
        ) {
            Box(
                modifier = Modifier
                    .background(
                        brush = Brush.linearGradient(listOf(PurpleMain, BlueMain)),
                        shape = CircleShape
                    )
                    .fillMaxSize(),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    painter = painterResource(R.drawable.plus),
                    contentDescription = "Button: New Article",
                    modifier = Modifier.size(28.dp),
                    tint = Color.White
                )
            }
        }
    }

    @Composable
    fun BottomNavItemText(selected: Boolean, text: String) {
        val color by animateColorAsState(
            if (selected) PurpleMain else (if (isSystemInDarkTheme()) DarkModeGrey else Color.Black),
            tween(500)
        )
        Text(
            text = text,
            color = color,
            fontSize = if (selected) 11.sp else 10.sp,
            fontWeight = if (selected) FontWeight.Bold else FontWeight.Normal,
            textAlign = TextAlign.Center
        )
    }

    @Composable
    fun BottomNav(navController: NavController) {
        var currentItemIdx by rememberSaveable { mutableStateOf(0) }

        val items = listOf(
            BottomNavItems.Universe,
            BottomNavItems.Me
        )
        BottomNavigation(
            modifier = Modifier
                .fillMaxWidth()
                .height(60.dp),
            backgroundColor = if (isSystemInDarkTheme()) DimDark else Color.White,
        ) {
            items.forEachIndexed { idx, item ->
                MyBottomNavigationItem(
                    modifier = Modifier.wrapContentSize(),
                    label = {
                        BottomNavItemText(currentItemIdx == idx, stringResource(item.titleResource))
                    },
                    icon = {
                        Icon(
                            modifier = Modifier.size(28.dp),
                            painter = painterResource(item.iconUnselected),
                            contentDescription = "Button: Universe"
                        )

                        AnimatedVisibility(
                            visible = currentItemIdx == idx,
                            enter = fadeIn(tween(500)),
                            exit = fadeOut(tween(500))
                        ) {
                            Icon(
                                modifier = Modifier.size(28.dp),
                                painter = painterResource(item.iconSelected),
                                contentDescription = "Button: Universe"
                            )
                        }
                    },
                    unselectedContentColor = UnselecetedGrey,
                    selectedContentColor = Color.Unspecified,
                    alwaysShowLabel = true,
                    selected = (currentItemIdx == idx),
                    onClick = {
                        currentItemIdx = idx
                        navController.navigate(item.route) {
                            launchSingleTop = true
                            popUpTo(BottomNavItems.Universe.route) {
                                saveState = true
                            }
                            restoreState = true
                        }
                    }
                )
            }

        }

    }
}